package com.dailywork.basepro.lambda;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * 深入 java8 第 03 篇 （ 函数式接口，常见的4个函数式接口 ）
 *
 * @author HuaZai(huazai @ aliyun.com)
 * <p>2018年4月15日 下午4:06:09 com.huazai.java8.lambda Java8-001
 */
public class Lambda03 {

    // 3.1.1 Consumer<T> 消费型接口

    public void test01() {
        this.con((e) -> System.out.println("消费型接口有去无回：" + e + "RMB"), 66666);
    }

    public void con(Consumer<Double> con, double salary) {
        con.accept(salary);
    }

    // 3.1.2 Supplier<T> : 供给型接口
    // 需求：产生任意个数的随机数

    public void test02() {
        List<Integer> list = this.getMathRNum(() -> (int) (Math.random() * 100), 10);
        list.stream().forEach(System.out::println);
    }

    public List<Integer> getMathRNum(Supplier<Integer> sup, int num) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        for (int i = 0; i < num; i++) {
            Integer b = sup.get();
            list.add(b);
        }
        return list;
    }

    // 3.1.3 Function<T, R> : 函数型接口
    // 需求：对一个任意的字符串进行处理，并返回一个经过逻辑处理后的字符串

    public void test03() {
        String result01 = this.strFun((str) -> str.substring(0, 2), "99.29383");
        System.out.println(result01);

        String result02 = this.strFun((str) -> str.toUpperCase(), "huazai");
        System.out.println(result02);
    }

    public String strFun(Function<String, String> fun, String str) {
        return fun.apply(str);
    }

    // 3.1.4 Predicate<T> : 断言型接口
    // 需求：将满足筛选条件的名字放入到集合中，并输出

    public void test04() {
        // 准备的测试数据
        List<Integer> list = Arrays.asList(1982, 1998, 2004, 1995, 2018, 1988, 1999);
        List<Integer> result = this.strPred((yar) -> yar >= 1995, list);
        result.stream().sorted().forEach(System.out::println);
    }

    public List<Integer> strPred(Predicate<Integer> pre, List<Integer> str) {
        List<Integer> list = new ArrayList<>();
        for (Integer string : str) {
            if (pre.test(string)) {
                list.add(string);
            }
        }
        return list;
    }
}
